package com.aabte.springbootopenfeigndemo.core.configuration;

import com.aabte.springbootopenfeigndemo.core.exception.ApplicationInfrastructureException;
import com.aabte.springbootopenfeigndemo.core.exception.ApplicationValidationException;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Logger;
import feign.Response;
import feign.codec.ErrorDecoder;
import feign.slf4j.Slf4jLogger;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;

@ComponentScan(basePackages = {"com.aabte.springbootopenfeigndemo.core"})
@Configuration
public class CoreAutoConfiguration {

    @ConditionalOnClass(Slf4jLogger.class)
    @Configuration
    public class FeignAutoConfiguration {
        @Resource
        private ObjectMapper objectMapper;

        @Bean
        public ErrorDecoder errorDecoder() {
            return new ErrorDecoder() {
                @Override
                public Exception decode(String methodKey, Response response) {
                    try (InputStream inputStream = response.body().asInputStream()) {
                        com.aabte.springbootopenfeigndemo.core.bean.Response responseBean = objectMapper.readValue(inputStream, com.aabte.springbootopenfeigndemo.core.bean.Response.class);
                        if (StringUtils.isBlank(responseBean.getCode())) {
                            throw new ApplicationInfrastructureException("sys.remote_error", response.toString());
                        }
                        if (StringUtils.startsWith(responseBean.getCode(), "sys.")) {
                            throw new ApplicationInfrastructureException(responseBean.getCode(), responseBean.getMsg());
                        }
                        throw new ApplicationValidationException(responseBean.getCode(), responseBean.getMsg());
                    } catch (IOException e) {
                        throw new ApplicationInfrastructureException("sys.remote_error", response.toString(), e);
                    }
                }
            };
        }

        @Bean
        public Logger logger() {
            return new Slf4jLogger();
        }
    }
}
